package status

import (
	"aquaman/app/infra/ecode"
	"github.com/pkg/errors"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"strconv"
	pb "aquaman/app/infra/ecode/pb"
)

// FromError convert error for service reply and try to convert it to grpc.Status.
func FromError(err error) *status.Status {
	err = errors.Cause(err)
	if code, ok := err.(ecode.Codes); ok {
		// TODO: deal with err
		if gst, err := gRPCStatusFromEcode(code); err == nil {
			return gst
		}
	}
	gst, _ := status.FromError(err)
	return gst
}

func gRPCStatusFromEcode(code ecode.Codes) (*status.Status, error) {
	var st *ecode.Status
	switch v := code.(type) {
	case *ecode.Status:
		st = v
	case ecode.Code:
		st = ecode.FromCode(v)
	default:
		st = ecode.Error(ecode.Code(code.Code()), code.Message())
	}
	gst := status.New(codes.Unknown, strconv.Itoa(st.Code()))
	pbe := &pb.Error{ErrCode: int64(st.Code()), ErrMsg: st.Message()}
	return gst.WithDetails(pbe)
}

